﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using web.data.entities;
using System.Configuration;
using Webdiyer.WebControls.Mvc;
using System.Web.UI;

namespace web.bussines
{
    public class account_service
    {
        #region user management
        public users getUserByID(int id)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.user_id == id).FirstOrDefault();

                return user;
            }
        }

        public users authenticateUser(string user_name, string password)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.username == user_name && p.password == password && p.user_status == 1).SingleOrDefault();
                return user;
            }
        }

        public users authenticateUserEmail(string email, string password)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.email == email && p.password == password && p.user_status == 1).SingleOrDefault();
                return user;
            }
        }

        public users authenticateAdmForgotPassword(string user_name, string email)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.username == null && p.email == email && p.user_status == 1).SingleOrDefault();
                return user;
            }
        }

        public int countUserByUserName(string user_name)
        {
            using (var data = new baseEntities())
            {
                var user = data.tbl_users.Where(p => p.username == user_name);
                return user != null ? user.Count() : 0;
            }
        }

        public void changePassword(users user)
        {
            using (var data = new baseEntities())
            {
                var user_change_password = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                user_change_password.password = user.password;
                user_change_password.salt = user.salt;
                data.SaveChanges();
            }
        }

        public void updateStatusUser(users user)
        {
            using (var data = new baseEntities())
            {
                var user_change_status = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();
                if (user_change_status != null)
                {
                    user_change_status.user_status = user.user_status;
                    data.SaveChanges();
                }

            }
        }
        //xoa user
        public void UserDelete(int userid)
        {
            using (var data = new baseEntities())
            {
                var item = data.tbl_users.Where(p => p.user_id == userid).SingleOrDefault();
                if (item != null)
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                }
            }
        }

        public int createUser(users user)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_users(user);
                data.SaveChanges();

                return user.user_id;
            }
        }

        public void editUser(users user)
        {
            using (var data = new baseEntities())
            {
                var edit_user = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                if (edit_user != null)
                {
                    edit_user.username = user.username;
                    edit_user.password = user.password;
                    edit_user.activation_code = user.activation_code;
                    edit_user.active_date = user.active_date;
                    edit_user.created_date = user.created_date;
                    edit_user.email = user.email;
                    edit_user.salt = user.salt;
                    edit_user.user_status = user.user_status;
                    data.SaveChanges();
                }

            }
        }

        public List<users> getListUser(int startRecord, int pageSize, out int total)
        {
            using (var data = new baseEntities())
            {
                total = data.tbl_users.OrderByDescending(p => p.user_id).Count();
                var list_user = data.tbl_users.OrderByDescending(p => p.user_id).Skip(startRecord).Take(pageSize).ToList();
                return list_user;
            }
        }

        public PagedList<users> getPageListUser(int pageindex, int pagesite, string text_search, int? group_id)
        {
            using (var data = new baseEntities())
            {
                IQueryable<users> list;
                if (group_id != null && group_id != 0)
                {
                    list = (from p in data.tbl_users
                            join urf in data.tbl_user_ref_roles on p.user_id equals urf.user_id
                            where urf.group_id == group_id
                            select p);
                }
                else
                {
                    list = (from p in data.tbl_users
                            select p);
                }

                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.username.Contains(text_search) || p.email.Contains(text_search));
                }

                list = list.OrderByDescending(p => p.user_id);

                return list.ToPagedList(pageindex, pagesite);
            }
        }

        public bool CheckEmailExists(string email)
        {
            using (var data = new baseEntities())
            {
                var user = (from p in data.tbl_users
                            where p.email == email
                            select p);
                if (user != null && user.Count() > 0)
                {
                    return false;
                }
                else {
                    return true;
                }
            }
        }
        #endregion

        #region user group

        public List<user_group> getListUserGroup()
        {
            using (var data = new baseEntities())
            {
                var list_group = data.tbl_user_group.Where(p => p.group_enable == true).OrderBy(p => p.group_id).ToList();
                return list_group;
            }
        }

        public void addGroupForUser(int group_id, int user_id)
        {
            using (var data = new baseEntities())
            {
                var check = data.tbl_user_ref_roles.Where(p => p.group_id == group_id && p.user_id == user_id);
                if (check == null || check.Count() == 0)
                {
                    user_ref_roles urr = new user_ref_roles();
                    urr.group_id = group_id;
                    urr.user_id = user_id;
                    urr.date_from = DateTime.Now;

                    data.AddTotbl_user_ref_roles(urr);
                    data.SaveChanges();
                }
            }
        }

        // xoa khoi group, group = -1: xoa tat
        public void deleteUserFromGroup(int group_id, int user_id)
        {
            using (var data = new baseEntities())
            {
                var list_item = data.tbl_user_ref_roles.Where(p => p.user_id == user_id && (p.group_id == group_id || group_id == -1)).ToList();

                foreach (var it in list_item)
                {
                    data.DeleteObject(it);
                }

                data.SaveChanges();
            }
        }

        public void deleteAllGroupOfUser(int user_id)
        {
            using (var data = new baseEntities())
            {
                var list = data.tbl_user_ref_roles.Where(p => p.user_id == user_id).ToList();
                foreach (var item in list)
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                }
            }
        }

        public List<int> getListGroupOfUser(int user_id)
        {
            using (var data = new baseEntities())
            {
                var list_group_id = (from p in data.tbl_user_ref_roles
                                     join g in data.tbl_user_group on p.group_id equals g.group_id
                                     where p.user_id == user_id && g.group_enable == true
                                     select (int)p.group_id).ToList();
                return list_group_id;
            }
        }

        public PagedList<user_group> getPageListGroup(int pageindex, int pagesite, string text_search)
        {
            using (var data = new baseEntities())
            {
                IQueryable<user_group> list;

                list = (from p in data.tbl_user_group
                        select p);

                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.group_name.Contains(text_search) || p.group_desc.Contains(text_search));
                }

                list = list.OrderByDescending(p => p.group_id);

                return list.ToPagedList(pageindex, pagesite);
            }
        }

        public void updateStatusGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                var group_change_enable = data.tbl_user_group.Where(p => p.group_id == group.group_id).SingleOrDefault();

                group_change_enable.group_enable = group.group_enable;
                data.SaveChanges();
            }
        }
        public user_group getGroupByID(int id)
        {
            using (var data = new baseEntities())
            {
                var group = data.tbl_user_group.Where(p => p.group_id == id).FirstOrDefault();
                return group;
            }
        }

        public List<user_group> getListGroupByParent(int? id)
        {
            using (var data = new baseEntities())
            {
                var list_group = data.tbl_user_group.Where(p => p.group_enable == true);

                if (id != null)
                {
                    list_group = list_group.Where(p => p.group_parent_id == id);
                }
                else
                {
                    list_group = list_group.Where(p => p.group_parent_id == null);
                }

                return list_group.ToList();
            }
        }

        public List<user_group> getListGroupBuilder(int? id)
        {
            List<user_group> sb = new List<user_group>();
            return getListGroupBuilder(ref sb, id, true);
        }

        public List<user_group> getListGroupBuilder(ref List<user_group> sb, int? id, bool root)
        {
            List<user_group> list_parent = getListGroupByParent(id);
            foreach (var item in list_parent)
            {
                if (!root)
                {
                    item.group_name = getGroupByID((int)item.group_parent_id).group_name + ">>" + item.group_name;
                    user_group gr = getGroupByID(id ?? 0);
                    foreach (var itemStr in sb)
                    {
                        if (itemStr.group_id == gr.group_id)
                        {
                            if (itemStr.group_name.Contains(">>"))
                            {
                                int laststr = itemStr.group_name.LastIndexOf(">>") + 2;
                                string addStr = itemStr.group_name.Substring(0, laststr);
                                item.group_name = addStr + item.group_name;
                            }
                        }
                    }
                }
                sb.Add(item);
                List<user_group> list_child = getListGroupByParent(item.group_id);
                if (list_child.Count() > 0)
                {
                    getListGroupBuilder(ref sb, item.group_id, false);
                }
            }
            return sb;
        }

        public int createGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_user_group(group);
                data.SaveChanges();

                return group.group_id;
            }
        }

        public void editGroup(user_group group)
        {
            using (var data = new baseEntities())
            {
                var edit_group = data.tbl_user_group.Where(p => p.group_id == group.group_id).SingleOrDefault();

                if (edit_group != null)
                {
                    edit_group.group_name = group.group_name;
                    edit_group.group_desc = group.group_desc;
                    edit_group.group_enable = group.group_enable;
                    edit_group.group_parent_id = group.group_parent_id;
                    data.SaveChanges();
                }

            }
        }
        #endregion

        #region page management
        public List<page> getListPageAccessByUser(int id)
        {
            using (var data = new baseEntities())
            {
                var list_page = (from u in data.tbl_users
                                 join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                 from e0 in r0.DefaultIfEmpty()
                                 join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                 from e1 in r1.DefaultIfEmpty()
                                 join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                 from e2 in r2.DefaultIfEmpty()
                                 join p in data.tbl_page on e2.page_id equals p.page_id
                                 where u.user_id == id && p.page_status == 1
                                 select p);

                return list_page.ToList();
            }
        }

        public bool checkPageAccessByUser(int id, string page_path)
        {
            using (var data = new baseEntities())
            {
                var list_page = (from u in data.tbl_users
                                 join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                 from e0 in r0.DefaultIfEmpty()
                                 join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                 from e1 in r1.DefaultIfEmpty()
                                 join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                 from e2 in r2.DefaultIfEmpty()
                                 join p in data.tbl_page on e2.page_id equals p.page_id
                                 where u.user_id == id && p.page_status == 1 && p.page_path == page_path && e1.group_enable == true
                                 select p).ToList();
                if (list_page.Count > 0)
                    return true;
                return false;
            }
        }

        public List<int> getListPageAccessByGroup(int id)
        {
            using (var data = new baseEntities())
            {
                var list_page = (from u in data.tbl_user_group
                                 join pr in data.tbl_page_role on u.group_id equals pr.group_id into r2
                                 from e2 in r2.DefaultIfEmpty()
                                 join p in data.tbl_page on e2.page_id equals p.page_id
                                 where u.group_id == id && p.page_status == 1
                                 select p.page_id);

                return list_page.ToList();
            }
        }

        public page getPageByID(int id)
        {
            using (var data = new baseEntities())
            {
                var page = data.tbl_page.Where(p => p.page_id == id).FirstOrDefault();
                return page;
            }
        }

        // lay danh sach page theo page cha - quan ly page
        public List<page> getListPageByParent(int? id)
        {
            using (var data = new baseEntities())
            {
                // var list_page = data.tbl_page.Where(p => p.page_status == 1);

                if (id != null)
                {
                    var list_page = data.tbl_page.Where(p => p.page_parent == id);
                    return list_page.ToList();
                }
                else
                {
                    var list_page = data.tbl_page.Where(p => p.page_parent == null);
                    return list_page.ToList();
                }
            }
        }

        public List<page> getPagerBuilder(int pageindex, int pagesite, string text_search, int? parent)
        {
            using (var data = new baseEntities())
            {
                IQueryable<page> list = getListPageBuilder(parent).AsQueryable<page>();

                if (!string.IsNullOrEmpty(text_search))
                {
                    list = list.Where(p => p.page_name.Contains(text_search) || p.page_path.Contains(text_search) || p.page_desc.Contains(text_search));
                }
                return list.ToList();
              //  list = list.OrderBy(p => p.page_order); 
              //  return list.ToPagedList(pageindex, pagesite);
            }
        }

        public List<page> getListPageBuilder(int? id)
        {
            List<page> sb = new List<page>();
            return getListPageBuilder(ref sb, id, true);
        }

        public List<page> getListPageBuilder(ref List<page> sb, int? id, bool root)
        {
            List<page> list_parent = getListPageByParent(id);
            foreach (var item in list_parent)
            {
                //if (!root)
                //{
                //    item.page_name = //getPageByID((int)item.page_parent).page_name +
                //        ">>" + item.page_name;
                //    page pa = getPageByID(id ?? 0);
                //    foreach (var itemStr in sb)
                //    {
                //        if (itemStr.page_id == pa.page_id)
                //        {
                //            if (itemStr.page_name.Contains(">>"))
                //            {
                //                int laststr = itemStr.page_name.LastIndexOf(">>") + 2;
                //                string addStr = itemStr.page_name.Substring(0, laststr);
                //                item.page_name = addStr + item.page_name;
                //            }
                //        }
                //    }
                //}
                sb.Add(item);
                List<page> list_child = getListPageByParent(item.page_id);
                if (list_child.Count() > 0)
                {
                    getListPageBuilder(ref sb, item.page_id, false);
                }
            }
            return sb;
        }
        //
        public void updateStatusPage(page page)
        {
            using (var data = new baseEntities())
            {
                var page_change_status = data.tbl_page.Where(p => p.page_id == page.page_id).SingleOrDefault();

                page_change_status.page_status = page.page_status;
                data.SaveChanges();
            }
        }

        public int createPage(page page)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_page(page);
                data.SaveChanges();

                return page.page_id;
            }
        }

        public void editPage(page page)
        {
            using (var data = new baseEntities())
            {
                var edit_page = data.tbl_page.Where(p => p.page_id == page.page_id).SingleOrDefault();

                if (edit_page != null)
                {
                    edit_page.page_name = page.page_name;
                    edit_page.page_desc = page.page_desc;
                    edit_page.page_path = page.page_path;
                    edit_page.page_order = page.page_order;
                    edit_page.page_status = page.page_status;
                    edit_page.page_type = page.page_type;
                    edit_page.page_parent = page.page_parent;
                    data.SaveChanges();
                }

            }
        } 

        public void deleteAllPageAccessOfGroup(int group_id)
        {
            using (var data = new baseEntities())
            {
                var list = data.tbl_page_role.Where(p => p.group_id == group_id).ToList();
                foreach (var item in list)
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                }
            }
        }

        public void createAccessPageforGroup(int group_id, string arr_page)
        {
            using (var data = new baseEntities())
            {
                var arr_page_id = arr_page.Split(',');
                foreach (var item in arr_page_id)
                {
                    page_role pr = new page_role();
                    pr.group_id = group_id;
                    pr.page_id = int.Parse(item);
                    pr.created_date = DateTime.Now;

                    data.AddTotbl_page_role(pr);
                    data.SaveChanges();
                }
            }
        }

        //thuy comment - no use
        //public List<page> getListTopPageParent(int id)
        //{
        //    using (var data = new baseEntities())
        //    {
        //        var list_page_access = (from u in data.tbl_users
        //                                join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
        //                                from e0 in r0.DefaultIfEmpty()
        //                                join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
        //                                from e1 in r1.DefaultIfEmpty()
        //                                join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
        //                                from e2 in r2.DefaultIfEmpty()
        //                                join p in data.tbl_page on e2.page_id equals p.page_id
        //                                where u.user_id == id && p.page_status == 1 && p.page_parent == null
        //                                select p);

        //        return list_page_access.ToList();
        //    }
        //}
        //thuy comment - no use
        //public List<page> getListMenuPageByTopPageID(int? id, int user_id)
        //{
        //    using (var data = new baseEntities())
        //    {
        //        var list_page_access = getListPageByParentID(id, user_id);

        //        return list_page_access.ToList();
        //    }
        //}

        // tao menu trong admin 
        public List<page> getListPageByParentID(int? id, int user_id)
        {
            using (var data = new baseEntities())
            {
                List<page> list_page_access = null;
                if (id == null)
                {
                    list_page_access = (from u in data.tbl_users
                                        join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                        from e0 in r0.DefaultIfEmpty()
                                        join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                        from e1 in r1.DefaultIfEmpty()
                                        join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                        from e2 in r2.DefaultIfEmpty()
                                        join p in data.tbl_page on e2.page_id equals p.page_id
                                        where u.user_id == user_id && p.page_status == 1 && p.page_type == 1 && p.page_parent == null
                                        select p).ToList();
                }
                else
                {
                    list_page_access = (from u in data.tbl_users
                                        join urr in data.tbl_user_ref_roles on u.user_id equals urr.user_id into r0
                                        from e0 in r0.DefaultIfEmpty()
                                        join ug in data.tbl_user_group on e0.group_id equals ug.group_id into r1
                                        from e1 in r1.DefaultIfEmpty()
                                        join pr in data.tbl_page_role on e1.group_id equals pr.group_id into r2
                                        from e2 in r2.DefaultIfEmpty()
                                        join p in data.tbl_page on e2.page_id equals p.page_id
                                        where u.user_id == user_id && p.page_status == 1 && p.page_type == 1 && p.page_parent == id
                                        select p).ToList();
                }

                return list_page_access;
            }
        }

        // create left menu
        public string MenuBuilderAdmin(int? id, int user_id, string uri)
        {
            return PageMenuBuilder(id, user_id, true, uri);
        }
        // create left menu
        public string PageMenuBuilder(int? id, int user_id, bool root, string uri)
        {
            Uri nuri = new Uri(uri);
            var arr = nuri.PathAndQuery.Split('/');
            string _url = uri + "/"; // + vao de so sanh

            List<page> list_parent = getListPageByParentID(id, user_id);
            StringBuilder strMenu = new StringBuilder();
            if (root)
                strMenu.Append("<ul>");
            else
                strMenu.Append("<ul id='addons'>");

            foreach (var item in list_parent)
            {
                //build child
                StringBuilder strChild = new StringBuilder();
                var is_activ_child = false;
                List<page> list_child = getListPageByParentID(item.page_id, user_id);
                if (list_child.Count() > 0)
                {
                    foreach (var page in list_child)
                    {
                        string str_c_class = "";

                        if (_url.Contains(page.page_path + "/") && !string.IsNullOrEmpty(page.page_path))
                        {
                            str_c_class = "current";
                            is_activ_child = true;
                        }
                        strChild.Append(string.Format("<li class='{0}'><a href='/vi{1}'>{2}</a></li>", str_c_class, page.page_path, page.page_name));
                        // sb.Write("\n");
                    }
                }
                //build parent
                string str_p_class = "";
                string str_p_href = "";
                if (root)
                {
                    if ((_url.Contains(item.page_path + "/") && !string.IsNullOrEmpty(item.page_path)) || is_activ_child == true)
                    {
                        str_p_class = "current";
                    }
                }
                if (!string.IsNullOrEmpty(item.page_path) && list_child.Count() <= 0) // page nam rieng
                    str_p_href = "/vi" + item.page_path;//+ "#pi" + item.page_id);
                else
                    str_p_href = "#pi" + item.page_id;

                strMenu.Append(string.Format("<li class='{0}'><a class='elements' href='{1}'>{2}</a>", str_p_class, str_p_href, item.page_name));
                if (list_child.Count() > 0)
                {
                    //add child to parent item
                    strMenu.Append("<span class='arrow'>&nbsp;</span>");
                    strMenu.Append(string.Format("<ul id='pi{0}'>{1}</ul>", item.page_id, strChild.ToString()));
                }
            }
            strMenu.Append("</ul>"); //close menu:)
            return strMenu.ToString();
        }

        #endregion

        #region customer management
        public int createCustomer(customer customer)
        {
            using (var data = new baseEntities())
            {
                data.AddTotbl_customer(customer);
                data.SaveChanges();

                return customer.customer_id;
            }
        }
        #endregion

        #region member management
        public void editUserMember(users user)
        {
            using (var data = new baseEntities())
            {
                var edit_user = data.tbl_users.Where(p => p.user_id == user.user_id).SingleOrDefault();

                if (edit_user != null)
                {
                    edit_user.email = user.email;
                    data.SaveChanges();
                }

            }
        }

        public void editUserMemberInfor(customer cus)
        {
            using (var data = new baseEntities())
            {
                var edit_cus = data.tbl_customer.Where(p => p.user_id == cus.user_id).FirstOrDefault();

                if (edit_cus != null)
                {
                    edit_cus.email = cus.email;
                    edit_cus.address = cus.address;
                    edit_cus.mobile = cus.mobile;
                    edit_cus.full_name = cus.full_name;
                    data.SaveChanges();
                }

            }
        }
        #endregion
    }
}
